package com.flipboard.bottomsheet.commons;

import com.flipboard.bottomsheet.BottomSheetLayout;
import com.flipboard.bottomsheet.OnSheetDismissedListener;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionManager;
import ohos.aafwk.ability.fraction.FractionScheduler;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.app.Context;
import ohos.utils.PacMap;

public class BottomSheetFragmentDelegate implements OnSheetDismissedListener {

    private static final String SAVED_SHOWS_BOTTOM_SHEET = "bottomsheet:savedBottomSheet";
    private static final String SAVED_BACK_STACK_ID = "bottomsheet:backStackId";
    private static final String SAVED_BOTTOM_SHEET_LAYOUT_ID = "bottomsheet:bottomSheetLayoutId";


    private int bottomSheetLayoutId = Component.ID_DEFAULT;//TODO NO_ID need to check
    private BottomSheetLayout bottomSheetLayout;
    private boolean dismissed;
    private boolean shownByMe;
    private boolean viewDestroyed;
    private boolean showsBottomSheet = true;
    private int backStackId = -1;

    private BottomSheetFragmentInterface sheetFragmentInterface;
    private Fraction fragment;


    public static BottomSheetFragmentDelegate create(BottomSheetFragmentInterface sheetFragmentInterface) {
        return new BottomSheetFragmentDelegate(sheetFragmentInterface);
    }

    private BottomSheetFragmentDelegate(BottomSheetFragmentInterface sheetFragmentInterface) {
        if (!(sheetFragmentInterface instanceof Fraction)) {
            throw new IllegalArgumentException("sheetFragmentInterface must be an instance of a Fragment too!");
        }

        this.sheetFragmentInterface = sheetFragmentInterface;
        this.fragment = (Fraction) sheetFragmentInterface;
    }

    public void show(FractionManager manager, int bottomSheetLayoutId) {
        dismissed = false;
        shownByMe = true;
        this.bottomSheetLayoutId = bottomSheetLayoutId;
        manager.startFractionScheduler()
                .add(0,fragment, String.valueOf(bottomSheetLayoutId)) //TODO int paramter need to check
                .submit();
    }

    public int show(FractionScheduler transaction,  int bottomSheetLayoutId) {
        dismissed = false;
        shownByMe = true;
        this.bottomSheetLayoutId = bottomSheetLayoutId;
        transaction.add(0,fragment, String.valueOf(bottomSheetLayoutId));
        viewDestroyed = false;
        backStackId = transaction.submit();
        return backStackId;
    }

    public void dismiss() {
        dismissInternal(/*allowStateLoss=*/false);
    }

    public void dismissAllowingStateLoss() {
        dismissInternal(/*allowStateLoss=*/true);
    }

    private void dismissInternal(boolean allowStateLoss) {
        if (dismissed) {
            return;
        }
        dismissed = true;
        shownByMe = false;
        if (bottomSheetLayout != null) {
            bottomSheetLayout.dismissSheet();
            bottomSheetLayout = null;
        }
        viewDestroyed = true;
        if (backStackId >= 0) {
            fragment.getFractionAbility();//TODO
            backStackId = -1;
        } else {
            //TODO
            //FractionScheduler ft = fragment.getFractionAbility().beginTransaction();
            FractionScheduler ft = null;
            ft.remove(fragment);
            if (allowStateLoss) {
                ft.submit(); //TODO
            } else {
                ft.submit();
            }
        }
    }

    public void onAttach(Context context) {
        if (!shownByMe) {
            dismissed = false;
        }
    }

    public void onDetach() {
        if (!shownByMe && !dismissed) {
            dismissed = true;
        }
    }

    public void onCreate(PacMap savedInstanceState) {
        showsBottomSheet = AccessFragmentInternals.getContainerId(fragment) == 0;

        if (savedInstanceState != null) {
            showsBottomSheet = savedInstanceState.getBooleanValue(SAVED_SHOWS_BOTTOM_SHEET, showsBottomSheet);
            backStackId = savedInstanceState.getIntValue(SAVED_BACK_STACK_ID, -1);
            bottomSheetLayoutId = savedInstanceState.getIntValue(SAVED_BOTTOM_SHEET_LAYOUT_ID, Component.INVISIBLE);//TODO no id need to check
        }
    }

    public LayoutScatter getLayoutInflater(/*PacMap savedInstanceState, LayoutScatter superInflater*/) {
        bottomSheetLayout = getBottomSheetLayout();
        if (bottomSheetLayout != null) {
            return LayoutScatter.getInstance(bottomSheetLayout.getContext());
        }
        return LayoutScatter.getInstance(fragment.getContext());
    }

    /**
     * @return this fragment sheet's {@link BottomSheetLayout}.
     */
    public BottomSheetLayout getBottomSheetLayout() {
        if (bottomSheetLayout == null) {
            bottomSheetLayout = findBottomSheetLayout();
        }

        return bottomSheetLayout;
    }

    private BottomSheetLayout findBottomSheetLayout() {
        Fraction parentFragment = fragment;
        if (parentFragment != null) {
            Component view = parentFragment.getComponent();
            if (view != null) {
                return (BottomSheetLayout) view.findComponentById(bottomSheetLayoutId);
            } else {
                return null;
            }
        }
        Ability parentActivity = fragment.getFractionAbility();
        if (parentActivity != null) {
            return (BottomSheetLayout) parentActivity.findComponentById(bottomSheetLayoutId);
        }
        return null;
    }

    public void onActivityCreated( PacMap savedInstanceState) {
        if (!showsBottomSheet) {
            return;
        }

        Component view = fragment.getComponent();
        if (view != null) {
            if (view.getComponentParent() != null) {
                throw new IllegalStateException("BottomSheetFragment can not be attached to a container view");
            }
        }
    }

    public void onStart() {
        if (bottomSheetLayout != null) {
            viewDestroyed = false;
            bottomSheetLayout.showWithSheetView(fragment.getComponent(), sheetFragmentInterface.getViewTransformer());
            bottomSheetLayout.addOnSheetDismissedListener(this);
        }
    }

    public void onSaveInstanceState(PacMap outState) {
        if (!showsBottomSheet) {
            outState.putBooleanValue(SAVED_SHOWS_BOTTOM_SHEET, false);
        }
        if (backStackId != -1) {
            outState.putIntValue(SAVED_BACK_STACK_ID, backStackId);
        }
        if (bottomSheetLayoutId != Component.ID_DEFAULT) {//TODO no id
            outState.putIntValue(SAVED_BOTTOM_SHEET_LAYOUT_ID, bottomSheetLayoutId);
        }
    }

    /**
     * Corresponding onDestroyView() method
     */
    public void onDestroyView() {
        if (bottomSheetLayout != null) {
            viewDestroyed = true;
            bottomSheetLayout.dismissSheet();
            bottomSheetLayout = null;
        }
    }
//    @Override
    public void onDismissed(BottomSheetLayout bottomSheetLayout) {
        if (!viewDestroyed) {
            dismissInternal(true);
        }
    }



}
